package com.uobgroup.ews.uam.core.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.uobgroup.ews.uam.core.configuration.AppConfig;
import com.uobgroup.ews.uam.core.dao.UAMUserDao;
import com.uobgroup.ews.uam.core.domain.Reference;
import com.uobgroup.ews.uam.core.domain.SecurityGroup;
import com.uobgroup.ews.uam.core.domain.UAMUser;
import com.uobgroup.ews.uam.core.model.Person;
import com.uobgroup.ews.uam.core.service.ldap.LDSService;

@Service
@Transactional
public class UAMUserServiceImpl implements UAMUserService {

   @Autowired
   UAMUserDao uAMUserDao;

   @Autowired
   LDSService ldsService;

   public long countAllUAMUsers() {
      return uAMUserDao.count();
   }

   public void deleteUAMUser(UAMUser uamUser) {
      uAMUserDao.delete(uamUser);
   }

   public UAMUser findUAMUser(Long id) {
      return uAMUserDao.findOne(id);
   }

   public List<UAMUser> findAllUAMUsers() {
      return uAMUserDao.findAllWithoutDeletion();
   }

   public List<UAMUser> findUAMUserEntries(int firstResult, int maxResults) {
      return uAMUserDao.findAll(firstResult / maxResults, maxResults);
   }

   public void saveUAMUser(UAMUser uamUser) {
      SecurityGroup profileSecurityGroup = uamUser.getProfile().getSecurityGroup();
      uAMUserDao.save(uamUser);

      // Assign user to the selected profile group
      Person person = ldsService.findUser(uamUser.getUsername());
      if (person != null) {
         SecurityGroup user = new SecurityGroup();
         user.setDisplayName(uamUser.getUsername());
         user.setDN(AppConfig.getProperty("ldap_dn_person"));
         ldsService.assignUserToProfile(profileSecurityGroup, user);
      }
   }

   public UAMUser updateUAMUser(UAMUser uamUser) {
      // Update the associate profile group
      UAMUser originalUser = uAMUserDao.findOne(uamUser.getId());
      SecurityGroup oldProfileSecurityGroup = new SecurityGroup();
      oldProfileSecurityGroup.setDisplayName(originalUser.getProfile().getSecurityGroup().getDisplayName());
      oldProfileSecurityGroup.setDN(originalUser.getProfile().getSecurityGroup().getDN());
      SecurityGroup newProfileSecurityGroup = null;
      if (originalUser.getProfile().getId() != uamUser.getProfile().getId()) {
         newProfileSecurityGroup = new SecurityGroup();
         newProfileSecurityGroup.setDisplayName(uamUser.getProfile().getSecurityGroup().getDisplayName());
         newProfileSecurityGroup.setDN(uamUser.getProfile().getSecurityGroup().getDN());
      }
      uamUser = uAMUserDao.update(uamUser);
      if (newProfileSecurityGroup != null) {
         SecurityGroup user = new SecurityGroup();
         user.setDisplayName(uamUser.getUsername());
         user.setDN(AppConfig.getProperty("ldap_dn_person"));
         ldsService.unassignUserFromProfile(oldProfileSecurityGroup, user);
         ldsService.assignUserToProfile(newProfileSecurityGroup, user);
      }
      return uamUser;
   }

   public UAMUser findUserbyUsername(String username) {
      return uAMUserDao.findUserbyUsername(username);

   }

   public boolean IsExitUser(String username) {
      return uAMUserDao.IsExist(username);
   }

   public List<UAMUser> findUAMUserFilter(String username, Boolean IsAdmin, Boolean IsActive, Boolean IsDeleted,
         Boolean IsLocked, int firstResult, int maxResults) {
      return uAMUserDao.findUAMUserFilter(username, IsAdmin, IsActive, IsDeleted, IsLocked, firstResult, maxResults);
   }

   @Override
   public long countUserThatHasCountryReference(Reference country) {
      return uAMUserDao.countUserThatHasCountryReference(country);
   }

   @Override
   public long countUAMUserFilter(String username, Boolean IsAdmin, Boolean IsActive, Boolean IsDeleted,
         Boolean IsLocked) {
      return uAMUserDao.countUAMUserFilter(username, IsAdmin, IsActive, IsDeleted, IsLocked);
   }
}
